﻿using System;
using System.Numerics;
using System.Runtime.InteropServices;

#region 游戏场景枚举类型
enum E_ScenceType
{
    //开始场景
    Begin,
    //游戏场景
    Game,
    //结束场景
    End,
}
#endregion

#region 格子结构体和枚举
//格子类型枚举
enum E_Grid_Type
{
    Normal,
    Boom,
    Pause,
    Tunnel,
}
//位置信息结构体
struct Vector2
{
    public int x;
    public int y; 
    public Vector2(int x,int y)
    {
        this.x = x;
        this.y = y;
    }
}
//格子结构体
struct Grid
{
    //格子类型
    public E_Grid_Type type;
    //格子位置
    public Vector2 pos;

    //初始化构造函数
    public Grid(int x,int y,E_Grid_Type type)
    {
        pos.x = x; pos.y = y;
        this.type = type;
    }

    //绘制格子
    public void Draw()
    {
                Console.SetCursorPosition(pos.x, pos.y);
        switch(type)
        {
            case E_Grid_Type.Normal:
                Console.ForegroundColor = ConsoleColor.White;
                Console.Write('□');
                break;
                case E_Grid_Type.Boom:
                Console.ForegroundColor = ConsoleColor.Red;
                Console.Write('●');
                break;
                case E_Grid_Type.Pause:
                Console.ForegroundColor = ConsoleColor.Blue;
                Console.Write('‖');
                break;
                case E_Grid_Type.Tunnel:
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.Write('¤');
                break;
        }
    }
}
#endregion

#region 地图结构体
struct Map
{
    public Grid[] grids;

    public Map(int x,int y,int num)
    {
        grids=new Grid[num];
        //用于位置改变技术的变量
        int indexX = 0;
        int indexY = 0;
        //x的步长
        int stepNum = 2;

        Random r=new Random();
        int randomNum;
        for(int i=0;i<num;i++)
        {
            randomNum=r.Next(0,101);
            if(randomNum<85||i==0||i==num-1)
            {
                grids[i].type = E_Grid_Type.Normal;
            }
            else if(randomNum>=85&&randomNum<90)
            {
                grids[i].type = E_Grid_Type.Boom;
            }
            else if(randomNum>=90&&randomNum<95)
            {
                grids[i].type=E_Grid_Type.Pause;
            }
            else
            {
                grids[i].type = E_Grid_Type.Tunnel;
            }

            //位置设置
            grids[i].pos=new Vector2 (x,y);
            //每次循环都变化位置
            if(indexX==10)
            {
                y += 1;
                indexY++;
                if(indexY==2)
                {
                    indexX = 0;
                    indexY = 0;
                    stepNum = -stepNum;
                }
            }
            else
            {
                x += stepNum;
                indexX++;
            }
          

        }
    }

    public void Draw()
    {
        for(int i=0;i<grids.Length;i++)
        {
            grids[i].Draw();
        }
    }
}
#endregion
class Program
{
    #region 控制台初始化
    static void ConsoleInit(int w, int h)
    {
        //基础设置
        //光标隐藏
        Console.CursorVisible = false;
        //舞台大小
        Console.SetWindowSize(w, h);
        Console.SetBufferSize(w, h);
    }
    #endregion

    #region 开始+结束场景
    static void BeginorEndScence(int w,int h,ref E_ScenceType nowScenceType)
    {
        Console.ForegroundColor = ConsoleColor.White;
        Console.SetCursorPosition(nowScenceType == E_ScenceType.Begin ? w / 2 - 3 : w / 2 - 4, 8);
        Console.Write(nowScenceType == E_ScenceType.Begin ? "飞行棋" : "游戏结束");
        //当前选项编号
        int nowSelfIndex = 0;
        bool isQuiteBegin = false;
        while(true)
        {
            isQuiteBegin=false;
            Console.SetCursorPosition(nowScenceType == E_ScenceType.Begin ? w / 2 - 4 : w / 2 - 5, 13);
            Console.ForegroundColor = nowSelfIndex == 0 ? ConsoleColor.Red : ConsoleColor.White;
            Console.Write(nowScenceType == E_ScenceType.Begin ? "开始游戏":"回到主菜单");
            Console.SetCursorPosition(w / 2 - 4, 14);
            Console.ForegroundColor = nowSelfIndex == 1 ? ConsoleColor.Red : ConsoleColor.White;
            Console.Write("结束游戏");

            //通过readkey可以得到一个输入的枚举类型
            switch (Console.ReadKey(true).Key)
            {
                case ConsoleKey.W:
                    nowSelfIndex--;
                    if(nowSelfIndex<0)
                    {
                       nowSelfIndex = 0;
                    }
                    break;
                case ConsoleKey.S:
                    nowSelfIndex++;
                    if(nowSelfIndex>1)
                    {
                        nowSelfIndex = 1; 
                    }
                    break;
                case ConsoleKey.J:
                    if(nowSelfIndex==0)
                    {
                        //进入游戏场景
                        //改变场景ID
                        nowScenceType = nowScenceType == E_ScenceType.Begin ? E_ScenceType.Game : E_ScenceType.Begin;
                        //退出当前循环
                        isQuiteBegin = true;
                    }
                    else
                    {
                        //退出游戏
                        Environment.Exit(0);
                    }
                    break;
            }
            //通过标识决定是否跳出循环
            if(isQuiteBegin)
            {
                break;
            }
        }
    }

    #endregion

    #region 绘制地图信息
    static void DrawWall(int w, int h)
    {
        Console.ForegroundColor = ConsoleColor.Red;
        //横墙
        for (int i = 0; i < w; i += 2)
        {
            Console.SetCursorPosition(i, 0);
            Console.Write('■');

            Console.SetCursorPosition(i, h - 1);
            Console.Write('■');

            Console.SetCursorPosition(i, h - 6);
            Console.Write('■');

            Console.SetCursorPosition(i, h - 11);
            Console.Write('■');
        }
        //竖墙
        for (int i = 0; i < h; i++)
        {
            Console.SetCursorPosition(0, i);
            Console.Write('■');
            Console.SetCursorPosition(w - 2, i);
            Console.Write('■');
        }

        //文字信息
        Console.ForegroundColor = ConsoleColor.White;
        Console.SetCursorPosition(2, h - 10);
        Console.Write("□:普通格子");
        Console.ForegroundColor = ConsoleColor.Blue;
        Console.SetCursorPosition(2, h - 9);
        Console.Write("‖:停止行动一回合");
        Console.ForegroundColor = ConsoleColor.Red;
        Console.SetCursorPosition(26, h - 9);
        Console.Write("●:倒退五格");
        Console.ForegroundColor = ConsoleColor.Yellow;
        Console.SetCursorPosition(2, h - 8);
        Console.Write("¤:随机倒退、暂停、前进");
        Console.ForegroundColor = ConsoleColor.Cyan;
        Console.SetCursorPosition(2, h - 7);
        Console.Write("★:玩家");
        Console.ForegroundColor = ConsoleColor.Magenta;
        Console.SetCursorPosition(12, h - 7);
        Console.Write("▲:电脑玩家");
        Console.ForegroundColor = ConsoleColor.Green;
        Console.SetCursorPosition(26, h - 7);
        Console.Write("◎:玩家和电脑重合");
        Console.ForegroundColor = ConsoleColor.White;
        Console.SetCursorPosition(2, h - 5);
        Console.Write("按任意键扔骰子");
    }
    #endregion

    #region 玩家枚举类型和结构体
    enum E_PlayerType
    {
        Player,
        Computer,
    }

    struct Player
    {
        public E_PlayerType type;
        //当前所在地图的哪一个索引的格子
        public int nowIndex;
        //是否暂停标识
        public bool isPause;

        public Player(int index,E_PlayerType type)
        {
            nowIndex = index;
            this.type = type;
            isPause = false;
        }

        public void Draw(Map mapInfo)
        {
            //从传入的地图中得到格子信息
            Grid grid = mapInfo.grids[nowIndex];
            //设置位置
            Console.SetCursorPosition(grid.pos.x, grid.pos.y);
            //画：设置颜色，设置图标
            switch(type)
            {
                case E_PlayerType.Player:
                    Console.ForegroundColor= ConsoleColor.Cyan;
                    Console.Write('★');
                    break;
                case E_PlayerType.Computer:
                    Console.ForegroundColor = ConsoleColor.Magenta;
                    Console.Write('▲');
                    break;
                default:
                    break;
            }
        }
    }
    #endregion

    #region 绘制玩家
    static void DrawPlayer(Player player,Player computer,Map map)
    {
        //重合时
        if(player.nowIndex==computer.nowIndex)
        {
            //得到重合位置
            Grid grid = map.grids[player.nowIndex];
            Console.ForegroundColor = ConsoleColor.DarkGreen;
            Console.SetCursorPosition(grid.pos.x,grid.pos.y);
            Console.Write('◎'); 
        }
        //不重合时
        else
        {
            player.Draw(map);
            computer.Draw(map);
        }
    }
    #endregion

    #region 擦除
    static void ClearInfo(int w,int h)
    {
        Console.SetCursorPosition(2, h - 5);
        Console.Write("                                  ");
        Console.SetCursorPosition(2, h - 4);
        Console.Write("                                  ");
        Console.SetCursorPosition(2, h - 3);
        Console.Write("                                  ");
        Console.SetCursorPosition(2, h - 2);
        Console.Write("                                  ");
    }
    #endregion

    #region 扔骰子
    static bool RandomMove(int w,int h,ref Player p,ref Player c,Map map)
    {
        ClearInfo(w, h);
        Console.ForegroundColor = p.type == E_PlayerType.Player ? ConsoleColor.Cyan : ConsoleColor.Magenta;

        if (p.isPause==true)
        {
            Console.SetCursorPosition(2,h-5);
            Console.Write("处于暂停点，{0}需要暂停一回合", p.type == E_PlayerType.Player ? "你" : "电脑");
            p.isPause=false;
            return false;
        }

        Random r=new Random();
        int randomNum=r.Next(1,7);
        p.nowIndex+=randomNum;
        //打印扔的点数
        Console.SetCursorPosition(2, h - 5);
        Console.Write("{0}扔出点数为{1}", p.type == E_PlayerType.Player ? "你" : "电脑",randomNum);

        //判断是否到终点
        if (p.nowIndex>=map.grids.Length-1)
        {
            p.nowIndex=map.grids.Length-1;
        Console.SetCursorPosition(2, h - 4);
            if(p.type == E_PlayerType.Player)
            {
                Console.Write("恭喜获胜");
            }
            else
            {
                Console.Write("失败");
            }
            Console.SetCursorPosition(2, h - 3);
            Console.Write("按任意键结束");
            return true;
        }
        else
        {
            //没有到终点，就判断当前所在格子类型
            Grid grid = map.grids[p.nowIndex];
            switch(grid.type)
            {
                case E_Grid_Type.Normal:
                    Console.SetCursorPosition(2, h - 4);
                    Console.Write("{0}到达安全位置", p.type == E_PlayerType.Player ? "你" : "电脑");
                    Console.SetCursorPosition(2, h - 3);
                    Console.Write("请按任意键让{0}开始扔骰子", p.type == E_PlayerType.Player ? "电脑" : "你");
                    break;
                case E_Grid_Type.Boom:
                    p.nowIndex -= 5;
                    if(p.nowIndex<0)
                    {
                        p.nowIndex = 0;
                    }
                    Console.SetCursorPosition(2, h - 4);
                    Console.Write("{0}踩到炸弹，退后5格", p.type == E_PlayerType.Player ? "你" : "电脑");
                    Console.SetCursorPosition(2, h - 3);
                    Console.Write("请按任意键让{0}开始扔骰子", p.type == E_PlayerType.Player ? "电脑" : "你");
                    break;
                case E_Grid_Type.Pause:
                    p.isPause = true;
                    break;
                case E_Grid_Type.Tunnel:
                    Console.SetCursorPosition(2, h - 4);
                    Console.Write("{0}踩到时空隧道，", p.type == E_PlayerType.Player ? "你" : "电脑");
                    randomNum = r.Next(1, 91);
                    if (randomNum < 30)
                    {
                        p.nowIndex -= 5;
                        if (p.nowIndex < 0)
                        {
                            p.nowIndex = 0;
                        }
                        Console.SetCursorPosition(2, h - 3);
                        Console.Write("触发倒退五格");
                    }
                    else if (randomNum >= 30 && randomNum <= 60)
                    {
                        p.isPause = true;
                        Console.SetCursorPosition(2, h - 3);
                        Console.Write("触发暂停一回合");
                    }
                    else
                    {
                        int temp = p.nowIndex;
                        p.nowIndex = c.nowIndex;
                        c.nowIndex = temp;
                        Console.SetCursorPosition(2, h - 3);
                        Console.Write("双方交换位置", p.type == E_PlayerType.Player ? "电脑" : "你");
                    }
                    Console.SetCursorPosition(2, h - 2);
                    Console.Write("请按任意键让{0}开始扔骰子", p.type == E_PlayerType.Player ? "电脑" : "你");
                    break;
            }
        }
        return false;
    }
    #endregion

    #region 游戏场景

    static bool PlayerRandoMove(int w, int h, ref Player p, ref Player c, Map map,ref E_ScenceType nowScenceType)
    {
        //玩家 
        Console.ReadKey(true);
        bool  isGameOver = RandomMove(w, h, ref p, ref c, map);
        map.Draw();
        DrawPlayer(p, c, map);
        if (isGameOver)
        {
            Console.ReadKey(true);
            nowScenceType = E_ScenceType.End;
        }
        return isGameOver;
    }

    static void GameScene(int w,int h,ref E_ScenceType nowScenceType)
    {
        DrawWall(w,h);
        Map map=new Map(14,3,80);
        map.Draw();
        Player player = new Player(0,E_PlayerType.Player);
        Player computer = new Player(0,E_PlayerType.Computer);
        DrawPlayer(player,computer,map);

        while (true)
        {
            ////玩家 
            //Console.ReadKey(true);
            //isGameOver=RandomMove(w, h, ref player, ref computer, map);
            //map.Draw();
            //DrawPlayer(player,computer,map);
            //if(isGameOver)
            //{
            //    Console.ReadKey(true);
            //    nowScenceType = E_ScenceType.End;
            //    break;
            //}
               
            if(PlayerRandoMove(w, h, ref player, ref computer, map,ref nowScenceType))
            {
                break;
            }

            ////电脑
            //Console.ReadKey(true);
            //isGameOver = RandomMove(w, h, ref computer, ref player, map);
            //map.Draw();
            //DrawPlayer(player, computer, map);
            //if (isGameOver)
            //{
            //    Console.ReadKey(true);
            //    nowScenceType = E_ScenceType.End;
            //    break;
            //}

            if (PlayerRandoMove(w, h, ref computer, ref player, map, ref nowScenceType))
            {
                break;
            }
        }
    }

    #endregion

    static void Main(string[] args)
    {
        #region 控制台初始化
        int w = 50;
        int h = 30;
        ConsoleInit(w, h);
        #endregion

        #region 场景选择
        E_ScenceType nowScenceType = E_ScenceType.Begin;
        while(true)
        {
            switch(nowScenceType)
            {
                case E_ScenceType.Begin:
                    Console.Clear();
                    BeginorEndScence(w,h,ref nowScenceType);
                    break;
                case E_ScenceType.Game:
                    Console.Clear();
                    GameScene(w,h,ref nowScenceType);
                    break;
                case E_ScenceType.End:
                    Console.Clear();
                    BeginorEndScence(w, h, ref nowScenceType);
                    break;
            }
        }
        #endregion

    }
 
}